from typing import List, Optional
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, insert, update, and_, desc
from sqlalchemy.orm import selectinload

from basic.models import (
    LogicalVersion,
    LogicalFile,
    RelationFileVersion
)
from basic.database import generate_random_string

async def create_version(db: AsyncSession, file_key: str, is_top: bool = False) -> LogicalVersion:
    """
    创建文件版本
    
    Args:
        db: 数据库会话
        file_key: 文件键
        is_top: 是否置顶
        
    Returns:
        新创建的版本
    """
    # 获取最新版本号
    version_number = 1
    stmt = (
        select(LogicalVersion)
        .join(
            RelationFileVersion,
            RelationFileVersion.version_key == LogicalVersion.key
        )
        .where(RelationFileVersion.file_key == file_key)
        .order_by(desc(LogicalVersion.version_number))
    )
    result = await db.execute(stmt)
    latest_version = result.scalar_one_or_none()
    
    if latest_version:
        version_number = latest_version.version_number + 1
    
    # 创建新版本
    new_version_key = generate_random_string(8)
    stmt = (
        insert(LogicalVersion)
        .values(
            key=new_version_key,
            version_number=version_number
        )
        .returning(LogicalVersion)
    )
    result = await db.execute(stmt)
    new_version = result.scalar_one()
    
    # 创建关联
    stmt = insert(RelationFileVersion).values(
        file_key=file_key,
        version_key=new_version_key,
        is_top=is_top
    )
    await db.execute(stmt)
    
    return new_version

async def get_versions(db: AsyncSession, file_key: str) -> List[LogicalVersion]:
    """
    获取文件的所有版本
    
    Args:
        db: 数据库会话
        file_key: 文件键
        
    Returns:
        版本列表
    """
    stmt = (
        select(LogicalVersion)
        .join(
            RelationFileVersion,
            RelationFileVersion.version_key == LogicalVersion.key
        )
        .where(RelationFileVersion.file_key == file_key)
    )
    result = await db.execute(stmt)
    versions = result.scalars().all()
    return versions

async def get_version(db: AsyncSession, version_key: str) -> Optional[LogicalVersion]:
    """
    获取特定版本
    
    Args:
        db: 数据库会话
        version_key: 版本键
        
    Returns:
        版本对象或None
    """
    stmt = select(LogicalVersion).where(LogicalVersion.key == version_key)
    result = await db.execute(stmt)
    version = result.scalar_one_or_none()
    return version

async def set_top_version(db: AsyncSession, file_key: str, version_key: str) -> bool:
    """
    设置置顶版本
    
    Args:
        db: 数据库会话
        file_key: 文件键
        version_key: 版本键
        
    Returns:
        是否成功设置
    """
    # 先取消所有置顶
    stmt = (
        update(RelationFileVersion)
        .where(RelationFileVersion.file_key == file_key)
        .values(is_top=False)
    )
    await db.execute(stmt)
    
    # 再设置新的置顶
    stmt = (
        update(RelationFileVersion)
        .where(
            and_(
                RelationFileVersion.file_key == file_key,
                RelationFileVersion.version_key == version_key
            )
        )
        .values(is_top=True)
    )
    await db.execute(stmt)
    
    return True 